import java.io.IOException;
import java.io.RandomAccessFile;

public class EXEBitChecker {
    
    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("Usage: java EXEBitChecker <exeFilePath>");
            return;
        }

        try (RandomAccessFile raf = new RandomAccessFile(args[0], "r")) {
            // Check MZ signature
            if (raf.read() != 'M' || raf.read() != 'Z') {
                System.out.println("Error: File is not a valid EXE");
                return;
            }

            // Read PE header offset from DOS stub
            raf.seek(0x3C);
            int peOffset = readLittleEndianInt(raf);

            // Verify PE signature
            raf.seek(peOffset);
            if (raf.read() != 'P' || raf.read() != 'E' || raf.read() != 0 || raf.read() != 0) {
                System.out.println("Error: Invalid PE signature");
                return;
            }

            // Skip COFF header (20 bytes)
            raf.skipBytes(20);

            // Read Magic number from optional header
            int magic = readLittleEndianShort(raf);

            switch (magic) {
                case 0x10b:
                    System.out.println("32-bit");
                    break;
                case 0x20b:
                    System.out.println("64-bit");
                    break;
                default:
                    System.out.println("Error: Unknown executable format");
            }
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    private static int readLittleEndianShort(RandomAccessFile raf) throws IOException {
        byte[] bytes = new byte[2];
        raf.readFully(bytes);
        return (bytes[0] & 0xFF) | ((bytes[1] & 0xFF) << 8);
    }

    private static int readLittleEndianInt(RandomAccessFile raf) throws IOException {
        byte[] bytes = new byte[4];
        raf.readFully(bytes);
        return (bytes[0] & 0xFF) 
            | (bytes[1] & 0xFF) << 8
            | (bytes[2] & 0xFF) << 16
            | (bytes[3] & 0xFF) << 24;
    }
}